package com.xjoyt.pay.gateway.aop;

import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;

import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.ui.Model;

import com.xjoyt.pay.gateway.PayGatewayApp;
import com.xjoyt.pay.gateway.annotations.CallbackApi;
import com.xjoyt.pay.gateway.po.CallbackLog;
import com.xjoyt.pay.gateway.services.CallbackLogService;

/**
 * 回调截面
 * 
 * @author Administrator
 *
 */
@Component
@Aspect
public class CallbackAspect extends AbstractAspect {

	@Around("execution(java.lang.String com.xjoyt.pay.gateway.controllers.*Controller.*(..)) "
			+ " && args(id,model) && @annotation(annotation) ")
	public Object invoke(ProceedingJoinPoint point, String id, Model model, CallbackApi annotation) {
		CallbackLog entity = new CallbackLog();
		entity.success = false;
		if (StringUtils.isNotBlank(id))
			entity.id = StringUtils.substring(id, 0, 50);
		entity.name = annotation.value();
		try {
			// 调用
			Object[] args = point.getArgs();
			Object val = point.proceed(args);
			entity.success = true;
			if (model != null) {
				Map<String, Object> map = model.asMap();
				if (map.containsKey("param")) {
					entity.param = CallbackAspect.this.toString(map.get("param"));
				}
				if (map.containsKey("callback")) {
					entity.callback = CallbackAspect.this.toString(map.get("callback"));
				}
				if (map.containsKey("companyId")) {
					entity.companyId = CallbackAspect.this.toString(map.get("companyId"));
				}
				if (map.containsKey("merchantId")) {
					entity.companyId = CallbackAspect.this.toString(map.get("merchantId"));
				}
				if (map.containsKey("distributorId")) {
					entity.companyId = CallbackAspect.this.toString(map.get("distributorId"));
				}
			}
			return val;
		} catch (Throwable e) {
			String errerName = "回调生异常";
			logger.error(errerName, e);
			e.printStackTrace();
			entity.exception = e.toString();
			return null;
		} finally {
			save(entity);
		}
	}

	private void save(CallbackLog entity) {
		ExecutorService threadPool = Executors.newCachedThreadPool();
		FutureTask<Object> future = new FutureTask<>(() -> {
			CallbackLogService service = PayGatewayApp.applicationContext.getBean(CallbackLogService.class);
			service.save(entity);
			return null;
		});
		threadPool.execute(future);
	}
}
